Adding a search bar to a static site like Eleventy can be tricky because there is no "server" to handle searches. However, we can build a fast, client-side search using a small JSON index and a tiny bit of JavaScript.

1. Create the Search Index

First, we need to create a file that contains all your blog data in a format JavaScript can read. Create a file named search-index.json.njk in your root folder.
File: search-index.json.njk

Code snippet

---
permalink: /search.json
---
[
{% for post in collections.post %}
{
"title": {{ post.data.title | dump | safe }},
"url": {{ post.url | dump | safe }},
"date": "{{ post.date | postDate }}"
}{% if not loop.last %},{% endif %}
{% endfor %}
]

This file generates a /search.json file every time you build your site.

---

2. Add the Search UI to the Sidebar

Go to your _includes/layout.njk and add the search input at the top of your <aside> tag.
Update your <aside>:

HTML

<aside>
<h3>Search</h3>
<input type="text" id="search-input" placeholder="Type to search..." style="width: 100%; padding: 8px; box-sizing: border-box; margin-bottom: 10px;">
<ul id="search-results" class="post-list" style="display: none; background: #f9f9f9; padding: 10px; border: 1px solid #ddd;"></ul>

<hr>

<h3>Archive</h3>
{# ... your existing collapsible tree code ... #}
</aside>

---

3. Add the Search Logic (JavaScript)

Add this script just before the closing </body> tag in your layout.njk. This script fetches the JSON file and filters the results as the user types.

HTML

<script>
const searchInput = document.getElementById('search-input');
const resultsList = document.getElementById('search-results');
let posts = [];

// 1. Fetch the index once
fetch('/search.json')
.then(response => response.json())
.then(data => posts = data);

// 2. Filter on input
searchInput.addEventListener('input', (e) => {
const term = e.target.value.toLowerCase();
resultsList.innerHTML = '';

if (term.length < 2) {
resultsList.style.display = 'none';
return;
}

const filtered = posts.filter(post =>
post.title.toLowerCase().includes(term)
);

if (filtered.length > 0) {
resultsList.style.display = 'block';
filtered.forEach(post => {
const li = document.createElement('li');
li.innerHTML = `<a href="${post.url}">${post.title}</a> <br> <small>${post.date}</small>`;
resultsList.appendChild(li);
});
} else {
resultsList.style.display = 'block';
resultsList.innerHTML = '<li>No matches found</li>';
}
});
</script>

---

How Client-Side Search Works

  1. The Index: 11ty generates a small list of all your posts (search.json).
  2. The Fetch: When a visitor loads your site, their browser downloads that tiny JSON file.
  3. The Instant Filter: As they type, the JavaScript instantly scans that local list. There is no waiting for a server response—it's lightning-fast.

4. Push to Cloudflare

Bash

git add .
git commit -m "Add client-side search"
git push origin main

Your blog is now highly functional! Since we have a search index and an archive, would you like to add an RSS feed so people can subscribe to your blog via their favorite reader?